package com.lyncs.ods.modules.company.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyncs.ods.constant.LyncsOdsConstant;
import com.lyncs.ods.modules.company.mapper.CompanyContactInfoMapper;
import com.lyncs.ods.modules.company.model.CompanyContactInfo;
import com.lyncs.ods.modules.company.service.CompanyContactInfoService;
import com.lyncs.ods.modules.txn.model.TxnCommonInfo;
import com.lyncs.ods.utils.TxnCommonUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 企业通讯录 服务实现类
 * </p>
 *
 * @author alex
 * @since 2022-03-29
 */
@Service
public class CompanyContactInfoServiceImpl extends ServiceImpl<CompanyContactInfoMapper, CompanyContactInfo> implements CompanyContactInfoService {

    @Override
    public List<CompanyContactInfo> getConcatInfoByCompanyIds(List<Long> companyIds, Integer type) {
        if (CollectionUtil.isEmpty(companyIds) || Objects.isNull(type)) {
            return List.of();
        }
        LambdaQueryChainWrapper<CompanyContactInfo> queryChainWrapper = this.lambdaQuery().eq(CompanyContactInfo::getStatus, LyncsOdsConstant.BindStatus.BIND.getKey());
        //理论上不会有or这种反向查询好友关系的场景
        if (LyncsOdsConstant.ContactType.SUPPLIER.getKey().equals(type)) {
            //查客户好友关系
            queryChainWrapper.and(wrapper -> wrapper.in(CompanyContactInfo::getCompanyId, companyIds).eq(CompanyContactInfo::getType, LyncsOdsConstant.ContactType.CUSTOMER.getKey()))
                    .or(wrapper -> wrapper.in(CompanyContactInfo::getRelationId, companyIds).eq(CompanyContactInfo::getType, LyncsOdsConstant.ContactType.SUPPLIER.getKey()));
        } else if (LyncsOdsConstant.ContactType.CUSTOMER.getKey().equals(type)) {
            //查供应商好友关系
            queryChainWrapper.and(wrapper -> wrapper.in(CompanyContactInfo::getCompanyId, companyIds).eq(CompanyContactInfo::getType, LyncsOdsConstant.ContactType.SUPPLIER.getKey()))
                    .or(wrapper -> wrapper.in(CompanyContactInfo::getRelationId, companyIds).eq(CompanyContactInfo::getType, LyncsOdsConstant.ContactType.CUSTOMER.getKey()));
        }
        return queryChainWrapper.list();
    }

    @Override
    public Map<Long, String> getConcatNameMap(List<Long> companyIds, Integer type) {
        if (CollectionUtil.isEmpty(companyIds) || Objects.isNull(type)) {
            return Map.of();
        }
        List<CompanyContactInfo> companyContactInfos = getConcatInfoByCompanyIds(companyIds, type);
        //暂不支持被动建立好友关系的情景，B类企业不会有查看好友的操作
        return companyContactInfos.stream().filter(info -> companyIds.contains(info.getCompanyId())).collect(Collectors.toMap(CompanyContactInfo::getRelationId, CompanyContactInfo::getNickname));
    }


    @Override
    public List<CompanyContactInfo> getConcatInfoByCompanyIds(Long companyId, List<Long> relationIds, Integer type) {
        if (Objects.isNull(companyId) || Objects.isNull(type)) {
            return List.of();
        }
        return this.lambdaQuery()
                .eq(CompanyContactInfo::getCompanyId, companyId)
                .in(CollectionUtil.isNotEmpty(relationIds), CompanyContactInfo::getRelationId, relationIds)
                .eq(CompanyContactInfo::getType, type)
                .eq(CompanyContactInfo::getStatus, LyncsOdsConstant.BindStatus.BIND.getKey())
                .list();
    }

    @Override
    public Map<Long, String> getConcatNameMap(Long companyId, List<Long> relationIds, Integer type) {
        if (Objects.isNull(companyId) || CollectionUtil.isEmpty(relationIds) || Objects.isNull(type)) {
            return Map.of();
        }
        List<CompanyContactInfo> companyContactInfos = getConcatInfoByCompanyIds(companyId, relationIds, type);
        //暂不支持被动建立好友关系的情景，B类企业不会有查看好友的操作
        return companyContactInfos.stream().collect(Collectors.toMap(CompanyContactInfo::getRelationId, CompanyContactInfo::getNickname));
    }

    @Override
    public CompanyContactInfo getConcatInfo(Long companyId, Long relationId) {
        if (Objects.isNull(companyId) || Objects.isNull(relationId)) {
            return null;
        }
        List<CompanyContactInfo> companyContactInfos = this.lambdaQuery()
                .eq(CompanyContactInfo::getCompanyId, companyId)
                .eq(CompanyContactInfo::getRelationId, relationId)
                .eq(CompanyContactInfo::getStatus, LyncsOdsConstant.BindStatus.BIND.getKey())
                .list();
        if (CollectionUtils.isEmpty(companyContactInfos)) {
            return null;
        }
        return companyContactInfos.get(0);
    }

    @Override
    public <T extends TxnCommonInfo> Map<String, String> getConcatNameMap(@NotNull List<T> commonInfos) {
        return getTxnConcatNameMap(commonInfos).values().stream()
                .collect(Collectors.toMap(TxnCommonUtils::buildCompanyRelationKey, CompanyContactInfo::getNickname, (o1, o2) -> o1));
    }

    @Override
    public <T extends TxnCommonInfo> Map<String, CompanyContactInfo> getTxnConcatNameMap(@NotNull List<T> commonInfos) {
        Map<Long, List<Long>> creatorCompanyIdMap = new HashMap<>(commonInfos.size());
        for (T info : commonInfos) {
            List<Long> companyIds = creatorCompanyIdMap.getOrDefault(info.getCreatorCompanyId(), new ArrayList<>());
            companyIds.add(info.getSellerId());
            companyIds.add(info.getBuyerId());
            creatorCompanyIdMap.put(info.getCreatorCompanyId(), companyIds);
        }
        LambdaQueryChainWrapper<CompanyContactInfo> lambdaQueryWrapper = this.lambdaQuery();
        creatorCompanyIdMap.forEach((k, v) -> lambdaQueryWrapper.or(wrapper -> wrapper.eq(CompanyContactInfo::getCompanyId, k).in(CompanyContactInfo::getRelationId, v)));
        List<CompanyContactInfo> contactInfos = lambdaQueryWrapper.list();
        return contactInfos.stream().collect(Collectors.toMap(TxnCommonUtils::buildCompanyRelationKey, o -> o, (o1, o2) -> o1));
    }

    @Override
    public <T extends TxnCommonInfo> Map<Long, Map<Long, CompanyContactInfo>> getTxnConcatMap(@NotNull List<T> commonInfos) {
        Map<Long, List<Long>> companyIdMap = new HashMap<>(commonInfos.size());
        for (T info : commonInfos) {
            List<Long> sellerContactIds = companyIdMap.getOrDefault(info.getSellerId(), new ArrayList<>());
            List<Long> buyerContactIds = companyIdMap.getOrDefault(info.getBuyerId(), new ArrayList<>());
            sellerContactIds.add(info.getBuyerId());
            buyerContactIds.add(info.getSellerId());
            companyIdMap.put(info.getBuyerId(), buyerContactIds);
            companyIdMap.put(info.getSellerId(), sellerContactIds);
        }
        if (MapUtils.isEmpty(companyIdMap)) {
            return Map.of();
        }
        LambdaQueryChainWrapper<CompanyContactInfo> lambdaQueryWrapper = this.lambdaQuery();
        companyIdMap.forEach((k, v) -> lambdaQueryWrapper.or(wrapper -> wrapper.eq(CompanyContactInfo::getCompanyId, k).in(CompanyContactInfo::getRelationId, v)));
        List<CompanyContactInfo> contactInfos = lambdaQueryWrapper.list();
        if (CollectionUtils.isEmpty(contactInfos)) {
            return Map.of();
        }
        return contactInfos.stream().collect(Collectors.groupingBy(CompanyContactInfo::getCompanyId, Collectors.toMap(CompanyContactInfo::getRelationId, o -> o, (o1, o2) -> o1)));
    }

    @Override
    public void removeBatch(@NotNull List<CompanyContactInfo> contactInfos) {
        this.baseMapper.removeBatch(contactInfos);
    }
}
